/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.iwords.api.web.alipay;


import com.alipay.api.util.AlipayNotify;
import com.iwords.api.web.base.BaseAction;
import com.iwords.constants.Constants;
import com.iwords.service.AccountServiceLocal;
import com.iwords.service.TeacherService;
import com.iwords.service.object.AccountEntity;
import com.iwords.service.object.TeacherEntity;

import com.iwords.utils.CodeUtils;
import com.iwords.utils.StringUtils;
import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.json.JSONException;
import org.json.JSONObject;

/**
 *
 * @author sunmellon
 */
@WebServlet(name = "IWordsAPIAlipayServlet", urlPatterns = {"/alipayStartAPI", "/alipayDiscountAPI", "/alipayReturnAPI", "/alipayNotifyAPI"})
public class IWordsAlipayServlet extends BaseAction<AccountEntity> {

    /**
     * 创建订单
     */
    void alipayStart(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException, JSONException {
        System.out.println("IWordsAlipayServlet.alipayStart()");
        AccountEntity account = new AccountEntity();
        JSONObject result = new JSONObject();
        try {
            String userid = request.getParameter("userid");
            if (StringUtils.isNotBlank(userid)) {
                account.setUserid(Long.parseLong(userid));
            }
            String teacherid = request.getParameter("teacherid");
            if (StringUtils.isNotBlank(teacherid)) {
                account.setTeacherid(Long.parseLong(teacherid));
            }
            String accountAmtStr = request.getParameter("total_fee");
            BigDecimal accountAmt = new BigDecimal(accountAmtStr);

            account.setAccountamt(accountAmt.multiply(new BigDecimal(100)).intValue());

            account.setStatus(AccountEntity.WAIT_PAY);
            account.setCreatetime(new Date());
            account.setUpdatetime(new Date());
            accountService.create(account);
            result.put(Constants.IS_SUCCESS, Boolean.TRUE);

            JSONObject defaultValue = new JSONObject().put("out_trade_id", account.getId());
            result.put(Constants.DEFAULT_VALUE, defaultValue);
        } catch (Exception e) {
            result.put(Constants.IS_SUCCESS, Boolean.FALSE);
            log("参数异常", e);
            result.put(Constants.MESSAGE, CodeUtils.encode("参数异常"));
        }
        jsonPrint(response, result);

    }
    @EJB
    AccountServiceLocal accountService;

    /**
     * 用户支付成功后，支付宝同步回调逻辑。
     * 以下是支付宝提供的api接口中jsp方式相应的说明：
     * 
     * 功能：支付宝页面跳转同步通知页面
     * 版本：3.2
     * 日期：2011-03-17
     * 说明：
     * 以下代码只是为了方便商户测试而提供的样例代码，商户可以根据自己网站的需要，按照技术文档编写,并非一定要使用该代码。
     * 该代码仅供学习和研究支付宝接口使用，只是提供一个参考。
     * //***********页面功能说明***********
     * 该页面可在本机电脑测试
     * 可放入HTML等美化页面的代码、商户业务逻辑程序代码
     * TRADE_FINISHED(表示交易已经成功结束，为普通即时到帐的交易状态成功标识);
     * TRADE_SUCCESS(表示交易已经成功结束，为高级即时到帐的交易状态成功标识);
     * 
     * @param request
     * @param response
     * @throws ServletException
     * @throws IOException 
     */
    void alipayReturn(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException, JSONException {

        System.out.println("IWordsAlipayServlet.alipayReturn()");
        JSONObject result = new JSONObject();
        //获取手机客户端发送回来的支付宝支付完成消息



        //获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//

        String trade_no = request.getParameter("trade_no");//支付宝交易号
        String order_no = request.getParameter("out_trade_no");//获取订单号
        String total_fee = request.getParameter("total_fee");//获取总金额
        System.out.println("trade_no = " + trade_no);
        System.out.println("order_no = " + order_no);
        System.out.println("total_fee = " + total_fee);

        String buyer_email = request.getParameter("buyer_email");//买家支付宝账号
        System.out.println("buyer_email = " + buyer_email);
        String trade_status = request.getParameter("trade_status");//交易状态

        String useridStr = request.getParameter("userid");
        Long userid = null;
        if (StringUtils.isNotBlank(useridStr)) {
            userid = Long.parseLong(useridStr);
        }




        //请在这里加上商户的业务逻辑程序代码
        System.out.println("trade_status=" + trade_status);


        if (order_no != null) {
            //首先更新支付宝账户信息
            AccountEntity account = accountService.find(Long.valueOf(order_no));

            if (account == null) {
                //对应的订单编号不存在
                result.put(Constants.IS_SUCCESS, Boolean.FALSE);
                result.put(Constants.MESSAGE, CodeUtils.encode("支付宝支付成功，爱词授权失败：orderno:" + order_no));

            } else if (!account.getUserid().equals(userid)) {
                //对应的客户不匹配
                result.put(Constants.IS_SUCCESS, Boolean.FALSE);
                result.put(Constants.MESSAGE, CodeUtils.encode("爱词授权失败：orderno:" + order_no + " 参数异常"));
            } else {

                account.setAlipayNumber(trade_no);
                account.setAlipayEmail(buyer_email);
                
                if (accountService.updateAccountForAlipay(account)) {
                    result.put(Constants.IS_SUCCESS, Boolean.TRUE);

                } else {
                    result.put(Constants.IS_SUCCESS, Boolean.FALSE);
                    result.put(Constants.MESSAGE, CodeUtils.encode("支付宝支付成功，爱词授权失败:order_no=" + trade_no));
                }



            }
        } else {
            result.put(Constants.IS_SUCCESS, Boolean.FALSE);
            result.put(Constants.MESSAGE, CodeUtils.encode("支付宝支付成功，爱词授权失败:order_no is null"));
        }
        //——请根据您的业务逻辑来编写程序（以下代码仅作参考）——
        jsonPrint(response, result);

    }
    @EJB
    TeacherService teacherService;

    /**
     * 判断推广Id的正确性。
     * 
     * @param request
     * @param response
     * @throws ServletException
     * @throws IOException 
     */
    void alipayDiscount(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException,JSONException {
       JSONObject result = new JSONObject();
       
            String discountId = request.getParameter("discountId");
            if (discountId != null || discountId.length() > 0) {
                TeacherEntity teacher = new TeacherEntity();
                teacher.setMarketingid(discountId);
                teacher = teacherService.findTeacherByMarktingID(teacher);
                if (teacher != null) {
                   
                    result.put(Constants.IS_SUCCESS, Boolean.TRUE);
                    JSONObject defaultValue = new JSONObject().put("teacherid", teacher.getTeacherid());
                    result.put(Constants.DEFAULT_VALUE, defaultValue);
                }else{
                    result.put(Constants.IS_SUCCESS, Boolean.FALSE);
                    result.put(Constants.MESSAGE   ,CodeUtils.encode("优惠券不存在"));
                }
            }else{
                result.put(Constants.IS_SUCCESS, Boolean.FALSE);
                result.put(Constants.MESSAGE   ,CodeUtils.encode("优惠券不存在"));
            }
            
        jsonPrint(response, result);
    }

    /**
     * 用户支付成功后，支付宝异步回调逻辑。
     * 
     * 以下是支付宝提供的api接口中jsp方式相应的说明：
     * 
     * 功能：支付宝服务器异步通知页面
     * 版本：3.2
     * 日期：2011-03-17
     * 说明：
     * 以下代码只是为了方便商户测试而提供的样例代码，商户可以根据自己网站的需要，按照技术文档编写,并非一定要使用该代码。
     * 该代码仅供学习和研究支付宝接口使用，只是提供一个参考。
     * **********页面功能说明***********
     * 创建该页面文件时，请留心该页面文件中无任何HTML代码及空格。
     * 该页面不能在本机电脑测试，请到服务器上做测试。请确保外部可以访问该页面。
     * 该页面调试工具请使用写文本函数logResult，该函数在com.alipay.util文件夹的AlipayNotify.java类文件中
     * 如果没有收到该页面返回的 success 信息，支付宝会在24小时内按一定的时间策略重发通知
     * TRADE_FINISHED(表示交易已经成功结束，为普通即时到帐的交易状态成功标识);
     * TRADE_SUCCESS(表示交易已经成功结束，为高级即时到帐的交易状态成功标识);
     * @param request
     * @param response
     * @throws ServletException
     * @throws IOException 
     */
    void alipayNotify(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        System.out.println("IWordsAlipayServlet.alipayNotify()");
        //获取手机客户端发送回来的
        Map<String, String> params = new HashMap<String, String>();
        Map requestParams = request.getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            //乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
            //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "UTF-8");
            params.put(name, valueStr);
        }



        //获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//

        String trade_no = request.getParameter("trade_no");				//支付宝交易号
        String order_no = request.getParameter("out_trade_no");	        //获取订单号
        String total_fee = request.getParameter("total_fee");	        //获取总金额
        String subject = new String(request.getParameter("subject").getBytes("ISO-8859-1"), "utf-8");//商品名称、订单名称
        String body = "";
        if (request.getParameter("body") != null) {
            body = new String(request.getParameter("body").getBytes("ISO-8859-1"), "utf-8");//商品描述、订单备注、描述
        }
        String buyer_email = request.getParameter("buyer_email");		//买家支付宝账号
        String trade_status = request.getParameter("trade_status");		//交易状态

        //获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//


        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        try {
            if (AlipayNotify.verify(params)) {//验证成功
                //////////////////////////////////////////////////////////////////////////////////////////
                //请在这里加上商户的业务逻辑程序代码

                //——请根据您的业务逻辑来编写程序（以下代码仅作参考）——

                if (trade_status.equals("TRADE_FINISHED") || trade_status.equals("TRADE_SUCCESS")) {
                    //判断该笔订单是否在商户网站中已经做过处理（可参考“集成教程”中“3.4返回数据处理”）
                    //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
                    //如果有做过处理，不执行商户的业务程序
                    AccountEntity account = new AccountEntity();
                    account.setId(Long.valueOf(order_no));
                    account.setAlipayEmail(buyer_email);
                    account.setAlipayNumber(trade_no);
                    if (accountService.updateAccountForAlipay(account)) {
                        out.println("success");	//请不要修改或删除
                    } else {
                        out.println("fail");
                    }


                } else {
                    //参数错误
                    out.println("fail");	//请不要修改或删除
                }

                //——请根据您的业务逻辑来编写程序（以上代码仅作参考）——

            } else {//验证失败
                out.println("fail");
            }
        } catch (Exception e) {
            log("回调异常", e);
            out.println("fail");
        } finally {
            out.close();
        }
    }

    @Override
    public AccountEntity initEntity(HttpServletRequest req) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void doProcess(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException, JSONException {
        System.out.println("request.getPathInfo() = " + request.getPathInfo());
        System.out.println("request.getServletPath() = " + request.getServletPath());
        String servletPath = request.getServletPath();
        System.out.println("processRequest(request, response) servletPath = " + servletPath);
        if ("/alipayStartAPI".equals(servletPath)) {
            System.out.println("alipayStart(request, response);");
            alipayStart(request, response);
        } else if ("/alipayDiscountAPI".equals(servletPath)) {
            System.out.println("alipayDiscount(request, response);");
            alipayDiscount(request, response);
        } else if ("/alipayReturnAPI".equals(servletPath)) {
            System.out.println("alipayReturn(request, response);");
            alipayReturn(request, response);
        } else if ("/alipayNotifyAPI".equals(servletPath)) {
            System.out.println("alipayNotify(request, response);");
            alipayNotify(request, response);
        } else {
            System.out.println("non(request, response); servletPath = " + servletPath);
        }
    }
}
